"""日志工具模块
提供统一的日志记录功能
"""
from flask import request
from flask_login import current_user
from functools import wraps
import traceback
import json
import logging
import os
# 延迟导入避免循环依赖
# from services.shared import db, SystemLog

def get_logger(name, level=logging.INFO):
    """
    获取配置好的日志记录器
    
    Args:
        name: 日志记录器名称
        level: 日志级别
        
    Returns:
        配置好的日志记录器
    """
    logger = logging.getLogger(name)
    logger.setLevel(level)
    
    # 如果已经有处理器，不再添加
    if logger.handlers:
        return logger
    
    # 创建控制台处理器
    console_handler = logging.StreamHandler()
    console_handler.setLevel(level)
    
    # 设置日志格式
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    )
    console_handler.setFormatter(formatter)
    
    # 添加处理器到日志记录器
    logger.addHandler(console_handler)
    
    return logger

def log_user_action(level, module, message, details=None, user_id=None, 
                   action=None, resource_type=None, resource_id=None, 
                   execution_time=None, status_code=None, severity=0, 
                   error_code=None, stack_trace=None, tags=None):
    """
    记录用户操作日志
    
    Args:
        level: 日志级别 (TRACE, DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY)
        module: 模块名称
        message: 日志消息
        details: 详细信息 (可选)
        user_id: 用户ID (可选，默认从当前登录用户获取)
        action: 具体操作类型 (可选)
        resource_type: 资源类型 (可选)
        resource_id: 资源ID (可选)
        execution_time: 执行时间（毫秒） (可选)
        status_code: 状态码 (可选)
        severity: 严重程度 0-10 (可选，默认0)
        error_code: 错误代码 (可选)
        stack_trace: 错误堆栈 (可选)
        tags: 标签列表 (可选)
    """
    try:
        # 使用完全延迟导入避免循环依赖
        from datetime import datetime
        
        # 直接导入具体的模型类，避免通过__init__.py
        from services.shared.models.system import SystemLog
        
        # 如果没有提供user_id，尝试从当前登录用户获取
        if user_id is None:
            try:
                from flask_login import current_user
                if hasattr(current_user, 'id'):
                    user_id = current_user.id
            except (RuntimeError, ImportError):
                # 在没有请求上下文时忽略
                pass
            
        # 处理标签
        tags_json = None
        if tags:
            import json
            tags_json = json.dumps(tags, ensure_ascii=False)
        
        # 生成请求ID（如果没有提供）
        req_id = None
        try:
            from flask import request
            if hasattr(request, 'headers') and request.headers.get('X-Request-ID'):
                req_id = request.headers.get('X-Request-ID')
        except (RuntimeError, ImportError):
            # 在没有request上下文时忽略
            pass
        
        if not req_id:
            import uuid
            req_id = str(uuid.uuid4())
        
        # 获取request对象（如果可用）
        request_obj = None
        try:
            from flask import request
            request_obj = request
        except (RuntimeError, ImportError):
            # 在没有request上下文时设为None
            request_obj = None
        
        # 创建日志记录
        log = SystemLog.create_log(
            level=level,
            module=module,
            message=message,
            details=details,
            user_id=user_id,
            request=request_obj,
            action=action,
            resource_type=resource_type,
            resource_id=resource_id,
            execution_time=execution_time,
            status_code=status_code,
            severity=severity,
            error_code=error_code,
            stack_trace=stack_trace,
            tags=tags_json,
            request_id=req_id
        )
        
        # 使用数据库连接池而不是Flask的db.session
        # 这样可以在Celery worker环境中正常工作
        from services.shared.db_pool import get_db_session, close_db_session
        session = get_db_session()
        try:
            session.add(log)
            session.commit()
        finally:
            close_db_session()
        
    except Exception as e:
        # 日志记录失败不应该影响主业务流程
        # 使用标准日志记录器记录错误，避免递归调用
        import logging
        import traceback
        fallback_logger = logging.getLogger('log_utils_fallback')
        fallback_logger.error(f"记录日志失败: {e}")
        fallback_logger.error(f"日志记录异常详情: {traceback.format_exc()}")

def log_system_event(level, module, message, details=None, action=None, 
                    resource_type=None, resource_id=None, execution_time=None, 
                    status_code=None, severity=0, error_code=None, stack_trace=None, tags=None):
    """
    记录系统事件日志（无用户关联）
    
    Args:
        level: 日志级别 (TRACE, DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY)
        module: 模块名称  
        message: 日志消息
        details: 详细信息 (可选)
        action: 具体操作类型 (可选)
        resource_type: 资源类型 (可选)
        resource_id: 资源ID (可选)
        execution_time: 执行时间（毫秒） (可选)
        status_code: 状态码 (可选)
        severity: 严重程度 0-10 (可选，默认0)
        error_code: 错误代码 (可选)
        stack_trace: 错误堆栈 (可选)
        tags: 标签列表 (可选)
    """
    log_user_action(level, module, message, details, user_id=None, 
                   action=action, resource_type=resource_type, resource_id=resource_id,
                   execution_time=execution_time, status_code=status_code, severity=severity,
                   error_code=error_code, stack_trace=stack_trace, tags=tags)

def log_security_event(message, details=None, user_id=None):
    """
    记录安全相关事件
    
    Args:
        message: 日志消息
        details: 详细信息 (可选)
        user_id: 用户ID (可选)
    """
    log_user_action('WARNING', 'security', message, details, user_id)

def log_error(module, message, details=None, user_id=None):
    """
    记录错误日志
    
    Args:
        module: 模块名称
        message: 错误消息
        details: 详细信息 (可选)
        user_id: 用户ID (可选)
    """
    log_user_action('ERROR', module, message, details, user_id)

def log_info(module, message, details=None, user_id=None):
    """
    记录信息日志
    
    Args:
        module: 模块名称
        message: 日志消息
        details: 详细信息 (可选)
        user_id: 用户ID (可选)
    """
    log_user_action('INFO', module, message, details, user_id)

def log_api_call(func):
    """
    API调用日志装饰器
    记录API调用和异常信息
    """
    @wraps(func)
    def wrapper(*args, **kwargs):
        module = f'api_{func.__module__.split(".")[-1]}'
        endpoint = request.endpoint
        method = request.method
        
        try:
            # 记录API调用
            log_info(
                module, 
                f'{method} {endpoint} - API调用开始',
                details=json.dumps({
                    'endpoint': endpoint,
                    'method': method,
                    'args': str(args),
                    'remote_addr': request.remote_addr
                }, ensure_ascii=False)
            )
            
            result = func(*args, **kwargs)
            
            # 记录成功调用
            log_info(
                module, 
                f'{method} {endpoint} - API调用成功'
            )
            
            return result
            
        except Exception as e:
            # 记录API异常
            error_details = {
                'endpoint': endpoint,
                'method': method,
                'exception_type': type(e).__name__,
                'exception_message': str(e),
                'traceback': traceback.format_exc(),
                'request_data': str(request.get_json()) if request.is_json else None,
                'remote_addr': request.remote_addr
            }
            
            log_error(
                module,
                f'{method} {endpoint} - API调用异常: {str(e)}',
                details=error_details
            )
            
            raise  # 重新抛出异常
    
    return wrapper

def log_login_attempt(username, success, ip_address=None, user_agent=None):
    """
    记录登录尝试
    
    Args:
        username: 用户名
        success: 是否成功
        ip_address: IP地址
        user_agent: 用户代理
    """
    level = 'INFO' if success else 'WARNING'
    message = f'用户 {username} 登录{"成功" if success else "失败"}'
    
    details = {
        'username': username,
        'success': success,
        'ip_address': ip_address,
        'user_agent': user_agent
    }
    
    log_user_action(
        level, 
        'auth', 
        message, 
        details=json.dumps(details, ensure_ascii=False),
        action='login',
        resource_type='user',
        resource_id=username,
        status_code=200 if success else 401,
        severity=1 if not success else 0,
        tags=['authentication', 'login']
    )

def log_task_operation(action, task_id, task_name, user_id=None, execution_time=None, 
                      status_code=None, error_message=None, details=None):
    """
    记录任务操作日志
    
    Args:
        action: 操作类型 (create, update, delete, execute, start, stop, pause, resume)
        task_id: 任务ID
        task_name: 任务名称
        user_id: 用户ID
        execution_time: 执行时间（毫秒）
        status_code: 状态码
        error_message: 错误消息
        details: 详细信息
    """
    level = 'ERROR' if error_message else 'INFO'
    message = f'任务 {task_name} ({task_id}) {action}'
    if error_message:
        message += f' 失败: {error_message}'
    
    severity = 3 if error_message else 0
    
    log_user_action(
        level=level,
        module='task_manager',
        message=message,
        details=details,
        user_id=user_id,
        action=action,
        resource_type='task',
        resource_id=str(task_id),
        execution_time=execution_time,
        status_code=status_code,
        severity=severity,
        error_code='TASK_ERROR' if error_message else None,
        tags=['task', action]
    )

def log_api_request(endpoint, method, status_code, execution_time, user_id=None, 
                   request_size=None, response_size=None, error_message=None):
    """
    记录API请求日志
    
    Args:
        endpoint: API端点
        method: HTTP方法
        status_code: HTTP状态码
        execution_time: 执行时间（毫秒）
        user_id: 用户ID
        request_size: 请求大小（字节）
        response_size: 响应大小（字节）
        error_message: 错误消息
    """
    level = 'ERROR' if status_code >= 400 else 'INFO'
    message = f'{method} {endpoint} - {status_code}'
    if error_message:
        message += f' - {error_message}'
    
    severity = 0
    if status_code >= 500:
        severity = 5
    elif status_code >= 400:
        severity = 2
    
    details = {
        'endpoint': endpoint,
        'method': method,
        'request_size': request_size,
        'response_size': response_size
    }
    
    log_user_action(
        level=level,
        module='api',
        message=message,
        details=json.dumps(details, ensure_ascii=False),
        user_id=user_id,
        action='api_request',
        resource_type='api',
        resource_id=endpoint,
        execution_time=execution_time,
        status_code=status_code,
        severity=severity,
        error_code=f'HTTP_{status_code}' if status_code >= 400 else None,
        tags=['api', method.lower()]
    )

def log_database_operation(operation, table_name, execution_time, affected_rows=None, 
                          error_message=None, query=None):
    """
    记录数据库操作日志
    
    Args:
        operation: 操作类型 (SELECT, INSERT, UPDATE, DELETE)
        table_name: 表名
        execution_time: 执行时间（毫秒）
        affected_rows: 影响的行数
        error_message: 错误消息
        query: SQL查询（可选，用于调试）
    """
    level = 'ERROR' if error_message else ('WARNING' if execution_time > 1000 else 'DEBUG')
    message = f'{operation} {table_name}'
    if error_message:
        message += f' 失败: {error_message}'
    elif affected_rows is not None:
        message += f' - {affected_rows} 行'
    
    severity = 0
    if error_message:
        severity = 4
    elif execution_time > 5000:  # 超过5秒的查询
        severity = 3
    elif execution_time > 1000:  # 超过1秒的查询
        severity = 1
    
    details = {
        'operation': operation,
        'table_name': table_name,
        'affected_rows': affected_rows,
        'query': query[:500] if query else None  # 限制查询长度
    }
    
    log_system_event(
        level=level,
        module='database',
        message=message,
        details=json.dumps(details, ensure_ascii=False),
        action=operation.lower(),
        resource_type='table',
        resource_id=table_name,
        execution_time=execution_time,
        severity=severity,
        error_code='DB_ERROR' if error_message else None,
        tags=['database', operation.lower()]
    )

def log_file_operation(operation, file_path, user_id=None, file_size=None, 
                      error_message=None, execution_time=None):
    """
    记录文件操作日志
    
    Args:
        operation: 操作类型 (create, read, update, delete, upload, download)
        file_path: 文件路径
        user_id: 用户ID
        file_size: 文件大小（字节）
        error_message: 错误消息
        execution_time: 执行时间（毫秒）
    """
    level = 'ERROR' if error_message else 'INFO'
    message = f'文件 {operation}: {file_path}'
    if error_message:
        message += f' 失败: {error_message}'
    
    severity = 2 if error_message else 0
    
    details = {
        'operation': operation,
        'file_path': file_path,
        'file_size': file_size
    }
    
    log_user_action(
        level=level,
        module='file_manager',
        message=message,
        details=json.dumps(details, ensure_ascii=False),
        user_id=user_id,
        action=operation,
        resource_type='file',
        resource_id=file_path,
        execution_time=execution_time,
        severity=severity,
        error_code='FILE_ERROR' if error_message else None,
        tags=['file', operation]
    )

def log_system_performance(metric_name, metric_value, threshold=None, unit='%'):
    """
    记录系统性能指标
    
    Args:
        metric_name: 指标名称 (cpu_usage, memory_usage, disk_usage等)
        metric_value: 指标值
        threshold: 阈值
        unit: 单位
    """
    level = 'WARNING' if threshold and metric_value > threshold else 'DEBUG'
    message = f'{metric_name}: {metric_value}{unit}'
    
    severity = 0
    if threshold and metric_value > threshold:
        if metric_value > threshold * 1.5:
            severity = 4
            level = 'ERROR'
        else:
            severity = 2
    
    details = {
        'metric_name': metric_name,
        'metric_value': metric_value,
        'threshold': threshold,
        'unit': unit
    }
    
    log_system_event(
        level=level,
        module='system_monitor',
        message=message,
        details=json.dumps(details, ensure_ascii=False),
        action='monitor',
        resource_type='system',
        resource_id=metric_name,
        severity=severity,
        tags=['performance', metric_name]
    )

def log_business_operation(level='INFO', module='business', message='', details='', 
                          operation_type='', resource_type='', resource_id='', **kwargs):
    """记录业务操作日志"""
    log_user_action(
        level=level,
        module=module,
        message=message,
        details=details,
        action=operation_type,
        resource_type=resource_type,
        resource_id=resource_id,
        tags=['business', operation_type],
        **kwargs
    )

def log_data_operation(level='INFO', module='data', message='', details='', 
                      operation='', table_name='', record_id='', **kwargs):
    """记录数据操作日志"""
    log_user_action(
        level=level,
        module=module,
        message=message,
        details=details,
        action=f'data_{operation}',
        resource_type='database_record',
        resource_id=f'{table_name}:{record_id}' if record_id else table_name,
        tags=['data', operation, table_name],
        **kwargs
    )

def log_integration_event(level='INFO', module='integration', message='', details='', 
                         service_name='', event_type='', **kwargs):
    """记录集成事件日志"""
    log_user_action(
        level=level,
        module=module,
        message=message,
        details=details,
        action=f'integration_{event_type}',
        resource_type='external_service',
        resource_id=service_name,
        tags=['integration', event_type, service_name],
        **kwargs
    )

def log_workflow_step(level='INFO', module='workflow', message='', details='', 
                     workflow_id='', step_name='', step_status='', **kwargs):
    """记录工作流步骤日志"""
    log_user_action(
        level=level,
        module=module,
        message=message,
        details=details,
        action=f'workflow_{step_status}',
        resource_type='workflow',
        resource_id=f'{workflow_id}:{step_name}',
        tags=['workflow', step_status, step_name],
        **kwargs
    )

def log_cache_operation(level='DEBUG', module='cache', message='', details='', 
                       operation='', cache_key='', **kwargs):
    """记录缓存操作日志"""
    log_user_action(
        level=level,
        module=module,
        message=message,
        details=details,
        action=f'cache_{operation}',
        resource_type='cache',
        resource_id=cache_key,
        tags=['cache', operation],
        **kwargs
    )

def log_notification_event(level='INFO', module='notification', message='', details='', 
                          notification_type='', recipient='', **kwargs):
    """记录通知事件日志"""
    log_user_action(
        level=level,
        module=module,
        message=message,
        details=details,
        action=f'notification_{notification_type}',
        resource_type='notification',
        resource_id=recipient,
        tags=['notification', notification_type],
        **kwargs
    )